package com.bjb.vr.common.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bjb.vr.common.ao.ResPackageAo;
import com.bjb.vr.common.ao.ResPackageDetailAo;
import com.bjb.vr.common.ao.ResPackageDetailRemoveAo;
import com.bjb.vr.common.ao.ResPackageInsertAo;
import com.bjb.vr.common.dto.*;
import com.bjb.vr.common.mapper.*;
import com.bjb.vr.common.result.BaseResult;
import com.bjb.vr.common.result.CommonResult;
import com.bjb.vr.common.utils.PageUtils;
import com.bjb.vr.common.vo.ResGroupVo;
import com.bjb.vr.common.vo.ResPackageDetailVo;
import com.bjb.vr.common.vo.ResPackageResourcesVo;
import com.github.yitter.idgen.YitIdHelper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.LongStream;
import java.util.stream.Stream;

/**
 * @author admin
 * @description 针对表【res_bundle_detail(资源包详情表)】的数据库操作Service
 * @createDate 2022-04-19 10:42:40
 */
@Service
public class ResBundleDetailService extends ServiceImpl<ResBundleDetailMapper, ResBundleDetail> {

    @Autowired
    private ResBundleDetailMapper resBundleDetailMapper;

    @Autowired
    private ResGroupMapper resGroupMapper;

    @Autowired
    private ResFavoritesMapper favoritesMapper;

    @Autowired
    private ResPlaycontentMapper playcontentMapper;

    @Resource
    private ResPlaylistMapper playlistMapper;

    @Resource
    private ResPlatformResourceMapper platformResourceMapper;

    @Resource
    private ResLocalResourceMapper localResourceMapper;


    /**
     * 查询当前资源包以外的其他资源内容，然后进行添加操作
     *
     * @param resPackageDetailAo
     * @return
     */
    public IPage<ResPackageResourcesVo> queryPackageResources(ResPackageDetailAo resPackageDetailAo) {
        PageUtils.setPageNo(resPackageDetailAo);
        List<ResPackageDetailVo> resPackageDetailVos = resBundleDetailMapper.queryPackageResources(resPackageDetailAo);
        Integer resPackageDetailVosSize = resBundleDetailMapper.queryPackageResourcesSize(resPackageDetailAo);

        // 数据封装
        List<ResPackageResourcesVo> resPackageResourcesVos = new ArrayList<>();
        resPackageDetailVos.stream().forEach(resPackageDetailVo -> {
            resPackageResourcesVos.add(new ResPackageResourcesVo(resPackageDetailVo.getResId(), resPackageDetailVo.getResName(), resPackageDetailVo.getCapacity()));
        });
        IPage<ResPackageResourcesVo> voIPage = new Page<>(resPackageDetailAo.getCurrent(), resPackageDetailAo.getSize(), resPackageDetailVosSize);
        voIPage.setRecords(resPackageResourcesVos);
        return voIPage;
    }

    /**
     * 资源包添加新资源
     *
     * @param resPackageInsertAo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean insertPackageResources(ResPackageInsertAo resPackageInsertAo) {
        List<ResPackageInsertAo.ResArray> resArray = resPackageInsertAo.getResArray();
        try {
            for (ResPackageInsertAo.ResArray array : resArray) {
                ResBundleDetail resBundleDetail = new ResBundleDetail();
                resBundleDetail.setResBundleId(resPackageInsertAo.getResBundleId());
                resBundleDetail.setContentId(array.getResId());
                resBundleDetail.setContentSize(array.getCapacity());
                this.save(resBundleDetail);
                // 同步数据到本地资源表中
                LambdaQueryWrapper<ResPlatformResource> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(ResPlatformResource::getResId, array.getResId());
                ResPlatformResource platformResource = platformResourceMapper.selectOne(queryWrapper);
                if (Objects.nonNull(platformResource)) {
                    ResLocalResource localResource = new ResLocalResource();
                    localResource.setResId(null);
                    BeanUtils.copyProperties(platformResource, localResource);
                    localResourceMapper.insert(localResource);
                }
            }
            return true;
        } catch (Exception e) {
            log.error(e.getMessage());
            return false;
        }
    }

    /**
     * 资源包删除已有资源
     *
     * @param resPackageDetailRemoveAo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean removePackageResources(ResPackageDetailRemoveAo resPackageDetailRemoveAo) {
        try {
            // 从资源包删除
            resBundleDetailMapper.deleteByResBundleId(resPackageDetailRemoveAo);
            // 从我的收藏删除
            favoritesMapper.deleteByResId(resPackageDetailRemoveAo);
            // 从课程列表中删除
            playcontentMapper.deleteByResId(resPackageDetailRemoveAo);
            // 从本地资源中删除
            localResourceMapper.deleteByResId(resPackageDetailRemoveAo);
            return true;
        } catch (Exception e) {
            log.error(e.getMessage());
            return false;
        }
    }

    /**
     * 判断资源包大小是否超过设备组内设备容量
     *
     * @param resPackageAo
     * @return
     */
    public BaseResult judgePackageCapcity(ResPackageAo resPackageAo) {
        Integer capacity = resPackageAo.getCapacity() * 1024;
        String[] split = resPackageAo.getGroupIds().split(",");
        long[] groupIds = Arrays.stream(split).flatMapToLong(s -> LongStream.of(Long.parseLong(s))).toArray();
        List<ResGroupVo> resGroupVos = resGroupMapper.queryGroupByIds(groupIds);
        for (ResGroupVo groupVo : resGroupVos) {
            Long remainMem = groupVo.getCapacity() * 1024 * 1024;
            String groupName = groupVo.getGroupName();
            if (capacity > remainMem) {
                String errMsg = "资源包大小已超过设备组[" + groupName + "]容量";
                log.error(errMsg);
                return CommonResult.Fail(errMsg).setResult(false);
            }
        }
        return CommonResult.Ok("资源大小未超过设备组容量").setResult(true);
    }

    /**
     * 资源包详情
     *
     * @return
     */
    public IPage<ResPackageDetailVo> getPackageResourcesDetail(ResPackageDetailAo resPackageDetailAo) {
        // 字典值查询替换
        MPJLambdaWrapper<ResPackageDetailVo> joinQuery = new MPJLambdaWrapper<>();
        joinQuery.select(ResBundleDetail::getId)
                .select(ResBundleDetail::getResBundleId)
                .selectAs(ResBundleDetail::getContentId, "resId")
                .selectAs(ResBundleDetail::getContentSize, "capacity")
                .selectAs(ResLocalResource::getResName, "resName")
                .selectAs(ResLocalResource::getPeriod, "period")
                .selectAs(ResLocalResource::getLevel, "level")
                .selectAs(ResLocalResource::getSubject, "subject")
                .selectAs(ResLocalResource::getResType, "type")
                .leftJoin(ResLocalResource.class, ResLocalResource::getResId, ResBundleDetail::getContentId);
        // 查询条件
        joinQuery.eq(Objects.nonNull(resPackageDetailAo.getResBundleId()), ResBundleDetail::getResBundleId, resPackageDetailAo.getResBundleId());
        joinQuery.in(StringUtils.isNotBlank(resPackageDetailAo.getPeriod()), ResLocalResource::getPeriod, resPackageDetailAo.getPeriod());
        joinQuery.in(StringUtils.isNotBlank(resPackageDetailAo.getLevel()), ResLocalResource::getLevel, resPackageDetailAo.getLevel());
        joinQuery.in(StringUtils.isNotBlank(resPackageDetailAo.getSubject()), ResLocalResource::getSubject, resPackageDetailAo.getSubject());
        joinQuery.in(StringUtils.isNotBlank(resPackageDetailAo.getResType()), ResLocalResource::getResType, resPackageDetailAo.getResType());
        joinQuery.like(StringUtils.isNotBlank(resPackageDetailAo.getResName()), ResLocalResource::getResName, resPackageDetailAo.getResName());
        // 执行查询
        IPage<ResPackageDetailVo> joinPage = resBundleDetailMapper.selectJoinPage(new Page<>(resPackageDetailAo.getCurrent(), resPackageDetailAo.getSize()), ResPackageDetailVo.class, joinQuery);
        return joinPage;
    }

    /**
     * 删除之前把资源是否在我的收藏和课程列表做个集合返回
     *
     * @param resPackageDetailRemoveAo
     * @return
     */
    public List<ResPackageDetailVo> BeforeRemovePackageResources(ResPackageDetailRemoveAo resPackageDetailRemoveAo) {
        Long[] resIds = resPackageDetailRemoveAo.getResIds();
        List<ResFavorites> resFavorites = favoritesMapper.selectList(new LambdaQueryWrapper<ResFavorites>().in(ResFavorites::getResId, resIds));
        List<ResPlaycontent> resPlaycontents = playcontentMapper.selectList(new LambdaQueryWrapper<ResPlaycontent>().in(ResPlaycontent::getResId, resIds));
        List<Long> collect = resFavorites.stream().map(ResFavorites::getResId).collect(Collectors.toList());
        List<Long> collect2 = resPlaycontents.stream().map(ResPlaycontent::getResId).collect(Collectors.toList());
        List<Long> longList = Stream.of(collect, collect2).flatMap(Collection::stream).distinct().collect(Collectors.toList());
        Long[] resIds2 = longList.stream().toArray(Long[]::new);
        if (resIds2.length <= 0) {
            return new ArrayList<>();
        }
        resPackageDetailRemoveAo.setResIds(resIds2);
        List<ResPackageDetailVo> packageDetailVos = resBundleDetailMapper.selectByResBundleIdAndResIds(resPackageDetailRemoveAo);
        return packageDetailVos;
    }

    /**
     * 通过产品包复制资源包
     *
     * @param tenantId
     * @param prodBundleId
     * @param resBundleId
     */
    public void copyResBundleDetailFromOptProd(String tenantId, Long prodBundleId, Long resBundleId) {
        List<ResBundleDetail> resBundleDetailList = resBundleDetailMapper.queryResBundleDetailFromOptProd(tenantId, prodBundleId, resBundleId);
        buildNeedInfo(tenantId, resBundleId, resBundleDetailList);
        this.saveBatch(resBundleDetailList);
    }


    public void buildNeedInfo(String tenantId, Long resBundleId, List<ResBundleDetail> resBundleDetailList) {
        if (resBundleDetailList != null && resBundleDetailList.size() > 0) {
            resBundleDetailList.forEach(
                    resBundleDetail -> {
                        resBundleDetail.setDataId(YitIdHelper.nextId());
                        resBundleDetail.setTenantId(tenantId);
                        resBundleDetail.setResBundleId(resBundleId);
                    }
            );
        }
    }
}
